package com.xiaomage.slide

import android.animation.ValueAnimator
import android.content.Context
import android.graphics.BitmapFactory
import android.support.v4.view.ViewConfigurationCompat
import android.util.AttributeSet
import android.util.DisplayMetrics
import android.view.MotionEvent
import android.view.ViewConfiguration
import android.view.WindowManager
import android.view.animation.LinearInterpolator
import android.widget.FrameLayout

/**
 * Created by Administrator on 2018/3/20 0020.
 */
class SlideUtilClass :FrameLayout{
    //测试21,22使用
    private var debugStateTwo=false
    constructor(context: Context):super(context)
    constructor(context: Context,attributeSet: AttributeSet):super(context,attributeSet)
    constructor(context: Context,attributeSet: AttributeSet,defStyleAttr:Int):super(context,attributeSet,defStyleAttr)
    enum class Direction{
        LEFT,RIGHT,NON
    }
    /**
     * 判定为拖动的最小移动像素数
     */
    private var mTouchSlop: Int = 0
    //左右自带距离，默认为13dp
    private val autoPadding=dip2px(13f)
    //正常图片宽度
    private val imageWidth=dip2px(150f)
    //正常图片高度
    private val imageHeight=dip2px(112.5f)
    //最大图片宽度
    private val imageWidthMax=dip2px(200f)
    //最大图片高度
    private val imageHeightMax=dip2px(150f)
    //中间图片距离左边的位置
    private val centerLeftMargin=(getWindowsWidth()-imageWidthMax)/2
    //中间图片向左可移动的最大距离
    private val centerImageMoveLeftMax=centerLeftMargin-autoPadding
    //左右两边距离顶部的距离
    private val leftAndRightTopMargin=(imageHeightMax-imageHeight)/2
    //左右两个图片的中间距离
    private val leftAndRightMaigin=getWindowsWidth()-2*autoPadding-2*imageWidth
    //最右边图片距离左边边框的距离
    private val rightImageMarginLeftParent=getWindowsWidth()-autoPadding-imageWidth
    //最右边图片移动到中间的距离
    private val rightImageToCenter=getWindowsWidth()-imageWidth-autoPadding-centerLeftMargin
    //一张图片旋转一周移动的X位置:以3个中间图片移动到左边为基准
    private val oneCircleX=centerImageMoveLeftMax*3
    //滑动的总距离
    private var dx=0f
    //滑动方向
    private var direction=Direction.NON
    //3个ImageView映射表
    private var imageId0=0
    private var imageId1=1
    private var imageId2=2
    //所有的图片对象
    private var lists:List<MyViewLikeImage>?=null
    //求X滑动速率
    //默认滑动1dp，图片移动2dp
    private val xRate=2.0f
    //设置斜切后的最大高度单元片
    private val skewMaxHeight=(imageHeightMax-imageHeight)/2
    //即：滑动的x坐标/图片移动的距离
   //private val xRate:Float=getWindowsWidth().toFloat()/oneCircleX.toFloat()
    //为了保证三个阶段移动同步，还需要算出每个阶段的同步频率，以中间图片（list[1]）移动到最左边作为标准
    private val oneMomentRate=1f
    private val twoMomentRate=((imageWidth.toFloat()+leftAndRightMaigin.toFloat())/centerImageMoveLeftMax.toFloat())*oneMomentRate
    private val threeMoment31=getWindowsWidth()/2-autoPadding-imageWidth
    private val threeMoment32=imageWidthMax/2
    private val threeMomentRate31=(threeMoment31
            /(centerImageMoveLeftMax/2))*oneMomentRate
    private val threeMomentRate32=(threeMoment32
    /(centerImageMoveLeftMax/2))*oneMomentRate
    //求出让左右两个图形中间对齐临街值，即此时两图片的宽度
    //266.875
    //正常宽度300.5
    private val keyWidth=(getWindowsWidth()-2*autoPadding-centerImageMoveLeftMax)/2
    //把第二阶段的平移改成放大和缩小以显示出3D效果,从左边移动到中心点的狐狸
    private val stateTwoCenterToLeft=centerImageMoveLeftMax/2
    //定义第二阶段缩放的最小长宽
    private val stateTwoMixWidth=imageWidth/5
    private val stateTwoMixHeight=imageHeight/5
    private val imageList= intArrayOf(R.drawable.w1,R.drawable.w2,
            R.drawable.w3,R.drawable.w4,R.drawable.w5,R.drawable.w6)
    //动画频率,即移动的速率，每移动1px索要的时间，默认为：循环一周占1000ms,即每移动1dx索要时间为animatorRate
    private val animatorRate=1000/oneCircleX
    //单次滑动距离
    private var oneDx=0f
    //卫浴最顶部的id：
    private var topId=1
    //防止重复绘制的id
    private var topIdBefore=1
    init {
        //val configuration = ViewConfiguration.get(context)
        // 获取TouchSlop值
       // mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration)
    }
    fun addView(lists:List<MyViewLikeImage>){
        this.lists=lists
        var i=0
        for(i in 0 until  lists.size){
            lists[i].setImageBitmap(BitmapFactory.decodeResource(resources,imageList[i]),imageWidth,imageWidthMax,imageHeight,imageHeightMax)
            addView(lists[i])

        }
        val params0=lists[0].layoutParams as FrameLayout.LayoutParams
        params0.leftMargin= autoPadding.toInt()
        params0.width= imageWidthMax.toInt()
        params0.height= imageHeightMax.toInt()
        lists[0].layoutParams=params0
        lists[0].forImage1(imageHeight,imageHeightMax,imageWidth,imageWidthMax)
        lists[0].setOnClickListener{
            // leftMove()
            onClik(0)
        }

        val params=lists[1].layoutParams as FrameLayout.LayoutParams
        params.width= imageWidthMax.toInt()
        params.height= imageHeightMax.toInt()
        params.leftMargin= centerLeftMargin.toInt()
        params.topMargin=dip2px(0f).toInt()
        lists[1].layoutParams=params
        //显示到最顶部
        lists[1].bringToFront()
        lists[1].setOnClickListener{
           // leftMove()
            onClik(1)
        }

        val params3=lists[2].layoutParams as FrameLayout.LayoutParams
        params3.leftMargin= rightImageMarginLeftParent.toInt()
        params3.width= imageWidthMax.toInt()
        params3.height= imageHeightMax.toInt()
        lists[2].layoutParams=params3
        lists[2].forImage1(imageHeight,imageHeightMax,imageWidth,imageWidthMax)
        lists[2].setOnClickListener{
            // leftMove()
            onClik(2)
        }

    }
    override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
        when(event.action){
            MotionEvent.ACTION_DOWN->{
                //按下操作
                oneDx=event.x
            }
            MotionEvent.ACTION_MOVE->{
                if (Math.abs((event.x-oneDx)) >mTouchSlop) {
                    return true
                }
            }
            MotionEvent.ACTION_UP->{
                //手指离开
               return false
            }
        }
        return super.onInterceptTouchEvent(event)
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        when(event.action){
            MotionEvent.ACTION_DOWN->{
                //按下操作
                oneDx=event.x
            }
            MotionEvent.ACTION_MOVE->{
                dx+=(event.x-oneDx)
                //移动操作
                if(oneDx>event.x){
                    //向左滑动
                    direction=Direction.LEFT
                    leftMove()
                }else if(oneDx<event.x){
                    //向右滑动
                    direction=Direction.RIGHT
                    rightMove()
                }else{
                    direction=Direction.NON
                }
                oneDx=event.x
            }
            MotionEvent.ACTION_UP->{
                //手指离开
                actvionUp()
            }
        }
        return true
    }
    //手指离开
    fun actvionUp(){
        if(lists==null || lists!!.isEmpty() ) return
        //三个图片实际移动位置，同时只保留第一个循环的情况
        var inDx=dx*xRate%oneCircleX

        if(inDx>0){
            inDx -= oneCircleX
        }
        if(inDx==0f) return
        //判断当前位置决定点击哪一个
        ForLog.showError("手指离开了topId："+topId)
        ForLog.showError("手指离开了dx："+dx)
        ForLog.showError("手指离开了inDx："+inDx)
        ForLog.showError("手指离开了centerImageMoveLeftMax：："+centerImageMoveLeftMax)
        ForLog.showError("手指离开了2*centerImageMoveLeftMax：："+2*centerImageMoveLeftMax)
        onClik(topId)
       /* if(inDx<=0 && inDx>=-centerImageMoveLeftMax){
            //第一阶段
            //第一阶段再分成两个阶段：11,12
            if(-inDx<(centerImageMoveLeftMax/2)){
                onClik(1)
            }else{
                onClik(2)
            }

        }else if(inDx<-centerImageMoveLeftMax &&
                inDx>=-(centerImageMoveLeftMax*2)){
            val momentDx=-(inDx+centerImageMoveLeftMax)
            if(momentDx<centerImageMoveLeftMax/2){
                onClik(2)
            }else{
                onClik(0)
            }
        }else{
            //第三阶段
            //第三阶段分割成 31,32
            //第三阶段课移动的最大长度
            val momentDx=-(inDx+centerImageMoveLeftMax*2)
            if(momentDx<centerImageMoveLeftMax/2){
                ForLog.showError("手指离开了阶段31")
                onClik(1)
            }else{
                ForLog.showError("手指离开了阶段32")
                onClik(0)
            }

        }*/

    }
    fun onClik(ids: Int){
        var inDx = when (ids) {
            0 -> (dx*xRate-centerImageMoveLeftMax)%oneCircleX
            1 -> dx*xRate%oneCircleX
            else -> (dx*xRate-2*centerImageMoveLeftMax)%oneCircleX
        }
        if(inDx>0){
            inDx -= oneCircleX
        }
        if(inDx==0f){
            return
        }
        //进行分割
        if(inDx>-1.5*centerImageMoveLeftMax){
            //需要逆时针旋转
            animatorDeal(inDx,0f,false,ids)
        }else{
            animatorDeal(inDx,-oneCircleX,false,ids)
        }
    }
    /**
     * 动画处理
     * 动画思路：通过动态修改dx来触发
     * from：dx当前位置
     * to：dx要移动的预计
     * leftMove
     */
    private fun animatorDeal(from:Float,to:Float,needLeftMove:Boolean,ids: Int){
        val valueAnimator=ValueAnimator.ofFloat(from, to)
        valueAnimator.duration= Math.abs((to-from)*animatorRate).toLong()
        valueAnimator.interpolator=LinearInterpolator()
        valueAnimator.addUpdateListener {
            value->
            dx= changeMode(value.animatedValue.toString().toFloat(),ids)
            if(needLeftMove){
                leftMove()
            }else{
                rightMove()
            }
        }
        valueAnimator.start()
    }
    fun leftMove(){
        if(lists==null || lists!!.isEmpty() ) return
        //三个图片实际移动位置，同时只保留第一个循环的情况
        var imageDx0=(dx*xRate-centerImageMoveLeftMax)%oneCircleX
        var imageDx1=dx*xRate%oneCircleX
        var imageDx2=(dx*xRate-2*centerImageMoveLeftMax)%oneCircleX
        if(imageDx0>0){
            imageDx0 -= oneCircleX
        }
        if(imageDx1>0){
            imageDx1 -= oneCircleX
        }
        if(imageDx2>0){
            imageDx2 -= oneCircleX
        }
        if(!debugStateTwo)  splitMoment(0,imageDx0,false)
        splitMoment(1,imageDx1,false)
        if(!debugStateTwo)  splitMoment(2,imageDx2,false)
    }
    //转换模式，由统一位移换成触摸位移，给动画使用
    private fun changeMode(value:Float,ids:Int):Float{
        //var imageDx0=(dx*xRate-centerImageMoveLeftMax)%oneCircleX
        //var imageDx1=dx*xRate%oneCircleX
       // var imageDx2=(dx*xRate-2*centerImageMoveLeftMax)%oneCircleX
        //0,1,2
        if(ids==0){
            return(value+centerImageMoveLeftMax)/xRate
        }else if(ids==2){
            return (value+2*centerImageMoveLeftMax)/xRate
        }else{
            return value/xRate
        }

    }
    fun rightMove(){
        //三个图片实际移动位置，同时只保留第一个循环的情况
        var imageDx0=(dx*xRate-centerImageMoveLeftMax)%oneCircleX
        var imageDx1=dx*xRate%oneCircleX
        var imageDx2=(dx*xRate-2*centerImageMoveLeftMax)%oneCircleX
        if(imageDx0>0){
            imageDx0 -= oneCircleX
        }
        if(imageDx1>0){
            imageDx1 -= oneCircleX
        }
        if(imageDx2>0){
            imageDx2 -= oneCircleX
        }
        if(!debugStateTwo)  splitMoment(0,imageDx0,true)
        splitMoment(1,imageDx1,true)
        if(!debugStateTwo)  splitMoment(2,imageDx2,true)
    }
    private fun becomeTop(idBegin:Int){
        //0-- -1-->2
        //1--- 0
        //2--- 1
        /*var ids=idBegin-1
        if(ids<0) ids=lists!!.size-1
        if(ids>=lists!!.size) ids =0
        lists!![ids].bringToFront()*/
        //0--1
        //1--2
        //2--3
        var id2=idBegin+1
        if(id2<0) id2=lists!!.size-1
        if(id2>=lists!!.size) id2=0
        lists!![id2].bringToFront()
        lists!![idBegin].bringToFront()
    }
    /**
     * 分割三个阶段：
     * di--->图片list下标
     * inDx:移动的位置
     * isRight:是否向右滑动，此时需要特别处理一下
     */
    private fun splitMoment(id:Int,inDx: Float,isRight:Boolean){
        //进行分割
        if(inDx<=0 && inDx>=-centerImageMoveLeftMax){
            //第一阶段
            //第一阶段再分成两个阶段：11,12
            if(-inDx<(centerImageMoveLeftMax/2)){

                leftMove(id,11,-inDx,isRight)
            }else{
                leftMove(id,12,-inDx,isRight)
            }

        }else if(inDx<-centerImageMoveLeftMax &&
                inDx>=-(centerImageMoveLeftMax*2)){
            //第二阶段
           // val momentDx=-(inDx+centerImageMoveLeftMax)
            //leftMove(id,2,momentDx*twoMomentRate)
            //为了展示3D效果，把阶段2分为阶段21和阶段22 *
            val momentDx=-(inDx+centerImageMoveLeftMax)
            if(momentDx<centerImageMoveLeftMax/2){
                leftMove(id,21,momentDx,isRight)
            }else{
                leftMove(id,22,momentDx,isRight)
            }
        }else{
            //第三阶段
            //第三阶段分割成 31,32
            //第三阶段课移动的最大长度
            val momentDx=-(inDx+centerImageMoveLeftMax*2)
            if(momentDx<centerImageMoveLeftMax/2){
                leftMove(id,31,momentDx,isRight)
            }else{
                leftMove(id,32,momentDx,isRight)
            }

        }
    }
    /**
     *  di--->图片list下标
     *  moment--->第几阶段，取值有：1,2,3
     *  momentDx--->该阶段移动的距离，记住，只是这个阶段的移动距离，并且已经根据速率换算完成了，并且momentDX>0
     *   isRight:是否向右滑动，此时需要特别处理一下
     */
    fun leftMove(id:Int,moment:Int,momentDx:Float,isRight:Boolean){
        when(moment){
            11->{
                val params=lists!![id].layoutParams as FrameLayout.LayoutParams
                params.leftMargin=(autoPadding+centerImageMoveLeftMax-momentDx).toInt()
                lists!![id].layoutParams=params
                val number=(skewMaxHeight*momentDx)/(centerImageMoveLeftMax/2)
                lists!![id].set11(number,keyWidth)
                if(!debugStateTwo) becomeTop(id)
                topId=id
            }
            12->{
                //阶段1，
                val params=lists!![id].layoutParams as FrameLayout.LayoutParams
                params.leftMargin=(autoPadding+centerImageMoveLeftMax-momentDx).toInt()
                lists!![id].layoutParams=params
                if(keyWidth>imageWidth){
                    val number=(skewMaxHeight*(momentDx-(imageWidthMax-keyWidth)))/(keyWidth-imageWidth)
                    lists!![id].set12(number,keyWidth)
                }else{
                    val number=((momentDx-centerImageMoveLeftMax/2)*skewMaxHeight)/(centerImageMoveLeftMax/2)
                    val xMove=number*(imageWidth-keyWidth)/skewMaxHeight
                    lists!![id].set12_2(number,keyWidth,xMove)
                }

            }21->{
                //阶段21
                val params=lists!![id].layoutParams as FrameLayout.LayoutParams
                params.leftMargin=(autoPadding+momentDx*twoMomentRate).toInt()
                lists!![id].layoutParams=params
                //此处进行缩放,缩小的长宽为：
                val xw=(momentDx*(imageWidth-stateTwoMixWidth))/stateTwoCenterToLeft
                val xh=(momentDx*(imageHeight-stateTwoMixHeight))/stateTwoCenterToLeft
                lists!![id].stateTwoChangeSmall(xw,xh/2)
                setImagePre()
            }
            22->{
                //阶段22
                val params=lists!![id].layoutParams as FrameLayout.LayoutParams
                params.leftMargin=(autoPadding+momentDx*twoMomentRate).toInt()
                lists!![id].layoutParams=params
                //此处进行放大,放大的长宽为：
                val xw=((momentDx-stateTwoCenterToLeft)*(imageWidth-stateTwoMixWidth))/stateTwoCenterToLeft
                val xh=((momentDx-stateTwoCenterToLeft)*(imageHeight-stateTwoMixHeight))/stateTwoCenterToLeft
                lists!![id].stateTwoChangeBig(xw,xh/2,skewMaxHeight,imageHeight,stateTwoMixWidth,stateTwoMixHeight)
                //设置下一张图片
                setImageNext()
            }
            31->{
                val params=lists!![id].layoutParams as FrameLayout.LayoutParams
                params.leftMargin=(rightImageToCenter-momentDx*threeMomentRate31+centerLeftMargin).toInt()
                lists!![id].layoutParams=params
                //dx/ threeMoment31=number/skewMaxHeight

                val number=(skewMaxHeight*momentDx*threeMomentRate31)/threeMoment31
                val xMove=(number*(imageWidth-keyWidth))/skewMaxHeight
                lists!![id].ser31_2(number,keyWidth,xMove)
                /*if(keyWidth>imageWidth){
                    val number=(skewMaxHeight*momentDx)/(keyWidth-imageWidth)
                    lists!![id].ser31(number,keyWidth)
                }else{
                    val number=(skewMaxHeight*momentDx)/centerImageMoveLeftMax/2
                    val xMove=(number*(imageWidth-keyWidth))/skewMaxHeight
                    lists!![id].ser31_2(number,keyWidth,xMove)
                }*/
            }
            32->{
                val params=lists!![id].layoutParams as FrameLayout.LayoutParams
                params.leftMargin=(getWindowsWidth()/2-(momentDx-centerImageMoveLeftMax/2)*threeMomentRate32).toInt()
                lists!![id].layoutParams=params
                //dx/ threeMoment32=number/skewMaxHeight
                val number=(skewMaxHeight*(momentDx-centerImageMoveLeftMax/2)*threeMomentRate32)/threeMoment32
                val xMove=(number*(imageWidthMax-keyWidth))/skewMaxHeight
                lists!![id].set32(number,keyWidth,xMove)
                topId=id
                if(!debugStateTwo) {
                    if(isRight){
                        //0-- -1---2
                        //1--  0
                        //2--  1
                        var id2=id-1
                        if(id2<0) id2=lists!!.size-1
                        if(id2>=lists!!.size) id2=0
                        lists!![id2].bringToFront()
                        lists!![id].bringToFront()
                    }else{
                        lists!![id].bringToFront()
                    }
                }
            }
        }

    }
    //设置下一张图片
    fun setImageNext(){
        ForLog.showError("替换下一张图片topId:"+topId)
        ForLog.showError("替换下一张图片topIdBefore:"+topIdBefore)
        if(topId==topIdBefore) return
        //顶部图片的id
        var topIdImage=when(topId){
            0->imageId0
            2->imageId2
            else->imageId1
        }
        var top=when(topId){
            0->1
            2->0
            else->2
        }
        var lastImageId=topIdImage+1
        if(lastImageId>=imageList.size){
            lastImageId=0
        }
        when(top){
            0->{
                imageId0=lastImageId
                lists!![0].setImageBitmap(BitmapFactory.decodeResource(resources,imageList[lastImageId]),
                        imageWidth,imageWidthMax,imageHeight,imageHeightMax)

            }
            2->{
                imageId2=lastImageId
                lists!![2].setImageBitmap(BitmapFactory.decodeResource(resources,imageList[lastImageId]),
                        imageWidth,imageWidthMax,imageHeight,imageHeightMax)
            }
            else->{
                imageId1=lastImageId
                lists!![1].setImageBitmap(BitmapFactory.decodeResource(resources,imageList[lastImageId]),
                        imageWidth,imageWidthMax,imageHeight,imageHeightMax)
            }
        }
        topIdBefore=topId
    }
    //设置上一张图片
    fun setImagePre(){
        if(topId==topIdBefore) return
        ForLog.showError("替换上一张图片topId:"+topId)
        ForLog.showError("替换上一张图片topIdBefore:"+topIdBefore)
        //顶部图片的id
        var topIdImage=when(topId){
            0->imageId0
            2->imageId2
            else->imageId1
        }
        var top=when(topId){
            0->2
            2->1
            else->0
        }
        var lastImageId=topIdImage-1
        if(lastImageId<0){
            lastImageId=imageList.size-1
        }
        when(top){
            0->{
                imageId0=lastImageId
                lists!![0].setImageBitmap(BitmapFactory.decodeResource(resources,imageList[lastImageId]),
                        imageWidth,imageWidthMax,imageHeight,imageHeightMax)

            }
            2->{
                imageId2=lastImageId
                lists!![2].setImageBitmap(BitmapFactory.decodeResource(resources,imageList[lastImageId]),
                        imageWidth,imageWidthMax,imageHeight,imageHeightMax)
            }
            else->{
                imageId1=lastImageId
                lists!![1].setImageBitmap(BitmapFactory.decodeResource(resources,imageList[lastImageId]),
                        imageWidth,imageWidthMax,imageHeight,imageHeightMax)
            }
        }
        topIdBefore=topId
    }
    fun dip2px(dpValue: Float): Float {
        val scale = context.resources.displayMetrics.density
        return dpValue * scale + 0.5f
    }

    /**
     * 获取屏幕宽度
     * @return
     */
    fun getWindowsWidth(): Int {
        val displayMetrics = DisplayMetrics()
        val windowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
        windowManager.defaultDisplay.getMetrics(displayMetrics)
        //返回px
        return displayMetrics.widthPixels
    }
}